import { L } from '../../Common/Language';
import { JXLocales } from '../../Common/Zh';
import { INVALID_VALUE } from './../../../Core/CoreDefine';
import BattleTextParse from './BattleTextParse';
import { JXBattleEvt, JXBtlAns_Result, JXBtlArrIx, JXBtlCamp } from './JXBattleDefine';
import { JXBattleMap, JXIdGenerater } from './JXBattleUtility';
import JXRBFlags from './JXRBFlags';
/** 战斗数据 */
export class JXBattleStorage {
    /**我方英雄的模板数据 */
    public defTPL: IMonsterBtl;
    /**参战双方信息 */
    public iBtlTeams: IMonsterBtl[];
    /** 只要没有输，就认为是赢了 */
    public isDefWin: boolean;
    /** 0: 平局， 1：胜利， 2： 失败 */
    public defResult: JXBtlAns_Result;
    /** 随机种子 */
    public randomSeed: string;
    /** 额外的参战对象 */
    public extras: JXSMap<IExtraParter>;
    /** 技能释放信息 */
    public skillInfos: JXAnsMap<JXAnsSkillInfo>;
    /** 技能效果信息 */
    public buffInfos: JXAnsMap<JXAnsBuffInfo>;
    /** 伤害信息 */
    public hurtInfos: JXAnsMap<JXAnsHurtInfo>;
    /** 治疗信息 */
    public addHpInfos: JXAnsMap<JXAnsAddHpInfo>;
    /** 生命提升信息 */
    public addMaxHpInfos: JXAnsMap<JXAnsAddMaxHpInfo>;
    /**軍營傷害信息 */
    public bracksHurtInfos: JXAnsMap<JXAnsBarracksHurtInfo>
    /** 最大血量记录(不包含血量提升部分) */
    public maxHps: JXMap<number>;
    /** 战斗开始血量(被动技能提升之前的血量) */
    public startHps: JXMap<number>;
    /** 结束血量记录(不包含血量提升部分) */
    public endHps: JXMap<number>;
    /**军营血量 */
    public barrackHps: number;
    public maxBarrackHps: number;
    public allHurt: number;
}

/** 战斗数据分析 */
export class JXBattleAnalysis extends JXBattleStorage {
    /** ID生成器 */
    public insIdGentor: JXIdGenerater;

    /** 过程信息 */
    public record: JXBattleMap<string, any>;
    public heroHurdInfo: JXBattleMap<number, number>;
    private _flags: JXRBFlags;
    private _bool: cc.Label = null;
    constructor(iBtlTeams: IMonsterBtl[], defTpl: IMonsterBtl) {
        super();
        this.insIdGentor = new JXIdGenerater('JXAns');
        this.iBtlTeams = iBtlTeams;
        this.defTPL = defTpl;
        this.record = new JXBattleMap<string, any>();
        this.maxHps = {};
        this.startHps = {};
        this.endHps = {};
        this.extras = {};
        this.skillInfos = {};
        this.buffInfos = {};
        this.hurtInfos = {};
        this.allHurt = 0;
        this.addHpInfos = {};
        this.addMaxHpInfos = {};
        this.bracksHurtInfos = {};
        this.barrackHps = 1000000;
        this.maxBarrackHps = 0;
        this._DPL_curPlayerID = new JXBattleMap<string, number>();
        this.heroHurdInfo = new JXBattleMap<number, number>();
    }

    public setFalgs(flag: JXRBFlags) {
        if (!this._flags) {
            this._flags = flag;
            this._flags.setHp(this.maxBarrackHps, this.barrackHps);
        }
    }

    public setDefToTeam(hero: IHeroBtlData) {
        let index = this.iBtlTeams[JXBtlCamp.Defenser].heroIds.indexOf(hero.heroId);
        let team = this.iBtlTeams[JXBtlCamp.Defenser];
        if (index == INVALID_VALUE) {
            team.tableIds.push(hero.tableId);
            team.heroIds.push(hero.heroId);
            team.partnerData.push(hero)
        }
    }
    //#region display 表现控制器
    /** 播放进度 */
    protected _DPL_curPlayerID: JXBattleMap<string, number>;
    public Get_DPL_curPlayID(hero: string): number {
        let num = this._DPL_curPlayerID.get(hero)
        return num ? num : 0;
    }

    public Set_DPL_curPlayID(hero: string, v: number) {
        this._DPL_curPlayerID.set(hero, v);
    }

    /** 记录战斗开始最大血量 */
    public setMaxHp(id: string, maxHp: number, startHp: number) {
        this.maxHps[id] = maxHp;
        this.startHps[id] = startHp;
    }


    /** 记录BUFF信息 */
    public setBuffInfo(buffAns: JXAnsBuffInfo) {
        this.buffInfos[buffAns.insId] = buffAns;
    }

    /** 记录战斗结束血量 */
    public setEndHp(id: string, endHp: number) {
        this.endHps[id] = Math.min(endHp, this.maxHps[id]);
    }

    /** 设置额外对象(比如说环境对象) */
    public setExtra(extra: IExtraParter) {
        this.extras[extra.id] = extra;
    }

    /** 记录治疗信息 */
    public setAddHpInfo(addHpAns: JXAnsAddHpInfo) {
        addHpAns.insId = this.insIdGentor.getNewId();
        this.addHpInfos[addHpAns.insId] = addHpAns;
    }


    /** 记录提升最大生命值 */
    public setAddMaxHpInfo(addMaxHpInfo: JXAnsAddMaxHpInfo) {
        addMaxHpInfo.insId = this.insIdGentor.getNewId();
        this.addMaxHpInfos[addMaxHpInfo.insId] = addMaxHpInfo;
    }


    /** 记录伤害信息 */
    public setHurtInfo(hurtAns: JXAnsHurtInfo) {
        hurtAns.insId = this.insIdGentor.getNewId();
        this.hurtInfos[hurtAns.insId] = hurtAns;
        this.setDelHurt(hurtAns.execer, hurtAns.damage)
    }

    /** 记录技能信息 */
    public setSkillInfo(skillAns: JXAnsSkillInfo) {
        this.skillInfos[skillAns.insId] = skillAns;
        for (let i = 0; i < skillAns.effects.length; i++) {
            let effect = skillAns.effects[i];
            let ansBuff = this.buffInfos[effect.buffInsId];
            ansBuff.insSkillId = skillAns.insId;
        }
    }

    /**記錄軍營傷害信息 */
    public setBracksDamege(bracksAns: JXAnsBarracksHurtInfo) {
        bracksAns.insId = this.insIdGentor.getNewId();
        this.bracksHurtInfos[bracksAns.insId] = bracksAns;
        this.barrackHps -= bracksAns.damage;
        if (this.barrackHps < 0) { return }
        this._flags.setHp(this.maxBarrackHps, this.barrackHps);
        this._flags.flagsShake();
        this._bool.string = L(JXLocales.fight.bool, this.barrackHps)
    }

    /** 入栈战斗日志 */
    public pushRecord(roleId: string, params: any[]) {
        let arr = this.record.get(roleId)
        if (!arr) {
            arr = []
        }
        arr.push(params);
        this.record.set(roleId, arr);
    }
    public write(...params: any[]) {
        let eventType = params[JXBtlArrIx.Zero]
        let id = params[JXBtlArrIx.One]
        switch (eventType) {
            case JXBattleEvt.ROLE_SKILL_PRESS: {
                let skillInfo = params[JXBtlArrIx.Two] as JXAnsSkillInfo;
                this.pushRecord(id, [eventType, skillInfo.insId]);
                break;
            }
            case JXBattleEvt.ROLE_SKILL_PRESS_END: {
                this.pushRecord(id, [eventType, params[JXBtlArrIx.Three]]);
                break;
            }
            case JXBattleEvt.ROLE_SKILL_HURT:
            case JXBattleEvt.ROLE_COM_ATK:
            case JXBattleEvt.ROLE_HURT_2_ATK: {
                let hurtInfo = params[JXBtlArrIx.Two] as JXAnsHurtInfo;
                this.setHurtInfo(hurtInfo);
                this.pushRecord(id, [eventType, hurtInfo.insId]);
                break;
            }
            case JXBattleEvt.ROLE_SKILL_ADDHP: {
                let addInfo = params[JXBtlArrIx.Two] as JXAnsAddHpInfo;
                this.setAddHpInfo(addInfo);
                this.pushRecord(id, [eventType, addInfo.insId]);
                break;
            }
            case JXBattleEvt.ROLE_ATK_2_HP: {
                let info = params[JXBtlArrIx.Two] as JXAnsAddHpInfo;
                this.setAddHpInfo(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.ROLE_ATK_2_PROTECT: {
                let info = params[JXBtlArrIx.Two] as JXAnsAddHpInfo;
                this.setAddHpInfo(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.ROLE_HURT_2_PROTECT: {
                let info = params[JXBtlArrIx.Two] as JXAnsAddHpInfo;
                this.setAddHpInfo(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.ROLE_HURT_2_HP: {
                let info = params[JXBtlArrIx.Two] as JXAnsAddHpInfo;
                this.setAddHpInfo(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.ROLE_SKILL_ADDMAXHP: {
                let info = params[JXBtlArrIx.Two] as JXAnsAddMaxHpInfo;
                this.setAddMaxHpInfo(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.HURT_BARKS: {
                let info = params[JXBtlArrIx.Two] as JXAnsBarracksHurtInfo;
                this.setBracksDamege(info);
                this.pushRecord(id, [eventType, info.insId]);
                break;
            }
            case JXBattleEvt.ROLE_END: {
                this.pushRecord(id, params);
                break;
            }
            default: {
                this.pushRecord(id, params);
                break;
            }
        }
    }


    /**统计我方英雄累计伤害信息*/
    protected setDelHurt(id: string, damage: number) {
        let team = this.iBtlTeams[JXBtlCamp.Defenser]
        let index = team.heroIds.indexOf(id);
        if (index === INVALID_VALUE) {
            return;
        }
        let heroData: IHeroBtlData = team.partnerData[index]
        if (!heroData) {
            return;
        }
        let value = this.heroHurdInfo.get(heroData.tableId);
        if (!value) value = 0;
        value += damage;
        this.allHurt += damage;
        this.heroHurdInfo.set(heroData.tableId, value);
    }

    /** display functions */
    public DPL_reSetDisPlayInfo() {
        this._DPL_curPlayerID.clear();

    }

    public DPL_getCurRecord(hero: string, isExe): any[] {
        let index = this.Get_DPL_curPlayID(hero);
        if (isExe) {
            let num = index + 1;
            this.Set_DPL_curPlayID(hero, num);
            (CC_DEV && this) && BattleTextParse.getTextReport(hero, this, true);
        } else {
            index -= 1;
        }
        return this.DPL_getCurRecordByID(hero, index);
    }

    public DPL_getCurRecordByID(heroId, idx: number): any[] {
        let record = this.record.get(heroId);
        record = record ? record : [];
        return record[idx];
    }

    public DPL_getRecordsByID(heroId: string): any[] {
        let record = this.record.get(heroId);
        record = record ? record : [];
        return record
    }

    public setDefResult(result: JXBtlAns_Result) {
        this.defResult = result;
        this.isDefWin = result != JXBtlAns_Result.Lost;
    }

    /**设置军营血量 */
    public setBarrackHps(hp: number, lab: cc.Label) {
        this.barrackHps = hp;
        this._bool = lab;
        this.maxBarrackHps = hp;
        console.log("军营血量为" + hp)
    }

    /**返回最多伤害英雄 */
    public maxHurtHero() {
        this.heroHurdInfo.forEach((v) => {

        })
    }
}